package common

import "time"

type Qos struct {
	Bucket chan struct{}

	limit int // qps
	close bool
}

func StartQoS(limit int) *Qos {
	q := new(Qos)
	q.limit = limit
	q.Bucket = make(chan struct{}, limit)

	go q.timer()
	return q
}

func (q *Qos) timer() {
	rate, remain := float32(q.limit)/100.0, float32(0)
	for range time.NewTicker(10 * time.Millisecond).C {
		if q.close {
			return
		}
		remain += rate
		count := int(remain)
		remain = remain - float32(count)
		for i := 0; i < count; i++ {
			select {
			case q.Bucket <- struct{}{}:
			default:
				// break if bucket if full
				break
			}
		}
	}
}

func (q *Qos) Close() {
	q.close = true
}
